package com.baymax.test.scene.demo;


import android.animation.Animator;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.RectEvaluator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.util.Property;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;

import androidx.annotation.Nullable;

import com.facebook.drawee.drawable.ArrayDrawable;


public class WkAnimatorDrawable extends ArrayDrawable {

    private Drawable layerMain;

    private final RectEvaluator evaluator = new RectEvaluator() {
        @Override
        public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
            Rect r = super.evaluate(fraction, startValue, endValue);
            Log.d("rect", "evaluate: " + fraction);
            invalidateSelf();
            return r;
        }
    };
    private final Interpolator interpolator = new AccelerateDecelerateInterpolator();

    @Nullable
    private Animator moveAnimator;
    Paint dotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


    public WkAnimatorDrawable() {
        super(new Drawable[]{new ColorDrawable()});
        layerMain = new ColorDrawable(Color.YELLOW);
        setDrawable(0, layerMain);
        dotPaint.setColor(Color.RED);
    }

    public Drawable setMainDrawable(Drawable newDrawable) {
        layerMain = newDrawable;
        return setDrawable(0, newDrawable);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        Drawable layerMain = getLayerMain();
        int centerY = layerMain.getBounds().centerY();
        canvas.drawCircle(8f, centerY, 4f, dotPaint);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
//        super.onBoundsChange(bounds);
        //不能 影响child
    }

    @Override
    public boolean isStateful() {
        return super.isStateful();
    }

    private Drawable getLayerMain() {
        return getDrawable(0);
    }


    public void mountToView(View view) {
        Rect rect = childRect2My(view);
        if (rect != null) {
            mountTo(rect);
        }
    }

    public void mountTo(Rect rect) {
        setMainDrawable(layerMain);
        getLayerMain().setBounds(rect);
    }

    public void umMount() {
        setMainDrawable(new ColorDrawable());
    }

    private final Property<Drawable, Rect> pp = new Property<Drawable, Rect>(Rect.class, "setDrawableRect") {
        @Override
        public Rect get(Drawable object) {
            return object.getBounds();
        }

        @Override
        public void set(Drawable object, Rect value) {
            object.setBounds(value);
        }
    };

    public void moveToView(View child) {
        Rect rect = childRect2My(child);
        if (rect != null) {
            moveTo(rect);
        }
    }

    public void moveTo(Rect dest) {
        if (moveAnimator != null) {
            moveAnimator.cancel();
        }
        Drawable layerMain = getLayerMain();
        Rect start = layerMain.copyBounds();
        boolean directUp = dest.top <= start.top;
        int childH = dest.height();
        Rect p80 = new Rect(dest);
        if (directUp) {
            p80.offset(0, childH / 10);
            insetOf(p80, 0, 0, 0, -childH / 5);
        } else {
            p80.offset(0, -childH / 10);
            insetOf(p80, 0, -childH / 5, 0, 0);
        }
        PropertyValuesHolder keyPvh = PropertyValuesHolder.ofKeyframe(pp,
                Keyframe.ofObject(0f, start),
                Keyframe.ofObject(0.80f, new Rect(dest)),
                Keyframe.ofObject(0.92f, p80),
                Keyframe.ofObject(1f, new Rect(dest))
        );
        keyPvh.setEvaluator(evaluator);

        moveAnimator = ObjectAnimator.ofPropertyValuesHolder(layerMain, keyPvh);
        moveAnimator.setDuration(600);
        moveAnimator.setInterpolator(interpolator);
        moveAnimator.start();
    }

    private Rect childRect2My(View child) {
        Callback callback = getCallback();
        if (callback instanceof ViewGroup parent) {
            Rect r = new Rect();
            child.getDrawingRect(r);
            parent.offsetDescendantRectToMyCoords(child, r);
            return r;
        }
        return null;
    }

    private static void insetOf(Rect rect, int l, int t, int r, int b) {
        rect.left += l;
        rect.top += t;
        rect.right -= r;
        rect.bottom -= b;
    }

}
